%%%-------------------------------------------------------------------
%%% File    : pipe_switch.erl
%%% Author  :  <vjache>
%%% Description : Divides stream between multiple pipes.
%%%
%%% Created : 18 Jun 2009 by  <vjache>
%%%-------------------------------------------------------------------
-module(pipe_switch).

%% API
-export([
		 new/2,
		 open/1,
		 push/2,
		 flush/1,
		 close/1]).

%%====================================================================
%% API
%%====================================================================
%%--------------------------------------------------------------------
%% Function: 
%% Description:
%%--------------------------------------------------------------------

new(Item2PipeIdFun,PipeFactoryFun) when is_function(Item2PipeIdFun, 1),
										is_function(PipeFactoryFun, 1) ->
	pipe:pipe_from_module(?MODULE, _Param={Item2PipeIdFun,PipeFactoryFun}, _NextPipe=terminal).

open({{Item2PipeIdFun,PipeFactoryFun},terminal=_NextPipe}) -> %%PipeState
    {Item2PipeIdFun,PipeFactoryFun,_PipeDict=dict:new()}.
push({Item2PipeIdFun,PipeFactoryFun,PipeDict},Item) ->
	case dict:find(PipeId=Item2PipeIdFun(Item), PipeDict) of
		{ok,PipeState} ->
			{Item2PipeIdFun,
			 PipeFactoryFun,
			 dict:store(PipeId, 
						pipe:push(PipeState,Item), 
						PipeDict)};
		error ->
			Pipe=PipeFactoryFun(PipeId),
			push({Item2PipeIdFun,
				  PipeFactoryFun,
				  dict:store(PipeId, 
							 pipe:open(Pipe), 
							 PipeDict)},
				 Item)
	end.
flush({_Item2PipeIdFun,_PipeFactoryFun,PipeDict}=S) ->
	dict:fold(fun(_PipeId, PipeState, _AccIn)->
					  pipe:flush(PipeState)
			  end, [], PipeDict),
	S.
close({_Item2PipeIdFun,_PipeFactoryFun,PipeDict}) ->
	dict:fold(fun(_PipeId, PipeState, _AccIn)->
					  ok=pipe:close(PipeState)
			  end, [], PipeDict),
	ok.


%%====================================================================
%% Internal functions
%%====================================================================

